<template>
  <div class="upload-container">
    <el-upload ref="uploadRef" v-model:file-list="fileList" :action="uploadUrl" list-type="text" :headers="headers"
      :multiple="multiple" :on-preview="handlePreview" :on-remove="handleRemove" :on-success="handleSuccess"
      :on-exceed="handleExceed" :before-upload="beforeUpload">
      <el-button v-if="multiple" slot="trigger" type="primary" size="small">上传文件</el-button>
      <template #tip>
        <div class="upload-tip">支持上传图片和 PDF 文件</div>
      </template>
    </el-upload>

    <!-- 文件预览对话框 -->
    <el-dialog v-model="dialogVisible" top="5vh" title="预览文件">
      <template #default>
        <div v-if="isPdf(dialogFileUrl)">
          <iframe :src="dialogFileUrl" style="width: 100%; height: 500px; border: none;" frameborder="0"></iframe>
        </div>
        <div v-else>
          <img :src="dialogFileUrl" alt="Preview Image" style="width: 100%; height: 500px; object-fit: contain;" />
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ElMessage } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'
import type { UploadProps, UploadUserFile } from 'element-plus'
import { getToken } from '@/utils/auth'
import { uploadApi, deleteFileApi } from '@/api/file'
const props = defineProps({
  modelValue: {
    type: [String, Array],
    default: ''
  },
  fileSize: {
    type: Number,
    default: 5
  },
  multiple: {
    type: Boolean,
    default: false
  },
  source: {
    type: String,
    default: null
  }
})
const uploadRef = ref()
const emit = defineEmits(['update:modelValue'])

// 上传地址
const uploadUrl = `${import.meta.env.VITE_APP_BASE_API}/file/upload?source=${props.source}`

// 请求头
const headers = {
  Authorization: getToken()
}

const fileList = ref<UploadUserFile[]>([])
const dialogFileUrl = ref('')
const dialogVisible = ref(false)

// 初始化文件列表
const initFileList = () => {
  if (!props.modelValue) return

  if (typeof props.modelValue === 'string') {
    fileList.value = [{
      name: props.modelValue.substring(props.modelValue.lastIndexOf('/') + 1),
      url: props.modelValue
    }]
  } else if (Array.isArray(props.modelValue)) {
    fileList.value = (props.modelValue as string[]).map(url => ({
      name: url.substring(url.lastIndexOf('/') + 1),
      url: url
    }))
  }
}

// 判断是否为 PDF 文件
const isPdf = (url: string) => {
  return /\.pdf$/i.test(url);
};

// 处理文件预览
const handlePreview: UploadProps['onPreview'] = (uploadFile) => {
  dialogFileUrl.value = uploadFile.url!;
  dialogVisible.value = true;
};

// 处理文件删除
const handleRemove: UploadProps['onRemove'] = async (uploadFile: any) => {
  if (props.multiple) {
    const urls = (props.modelValue as string[]).filter(url => url !== uploadFile.url)
    emit('update:modelValue', urls)
  } else {
    emit('update:modelValue', '')
  }
}

// 处理上传成功
const handleSuccess: UploadProps['onSuccess'] = async (response, file, fileList) => {
  if (response.code === 200) {
    const url = response.data;
    if (props.multiple) {
      // 确保追加到现有的 modelValue
      const urls = Array.isArray(props.modelValue) ? [...props.modelValue] : [];
      urls.push(url);
      emit('update:modelValue', urls);

      // 更新 fileList
      fileList.value = urls.map(u => ({
        name: u.substring(u.lastIndexOf('/') + 1),
        url: u
      }));
    } else {
      // 单文件模式直接替换
      emit('update:modelValue', url);
      fileList.value = [{
        name: url.substring(url.lastIndexOf('/') + 1),
        url: url
      }];
    }
    ElMessage.success('上传成功');
  } else {
    ElMessage.error('上传失败');
  }
};

// 处理超出限制
const handleExceed: UploadProps['onExceed'] = () => {
  ElMessage.warning('超出上传限制');
}

// 上传前的校验
const beforeUpload: UploadProps['beforeUpload'] = (file) => {
  if (file.size / 1024 / 1024 > props.fileSize) {
    ElMessage.error(`文件大小不能超过 ${props.fileSize}MB`);
    return false;
  }
  return true;
}
const clearFiles = () => {
  fileList.value = []
}
// 监听modelValue变化
watch(() => props.modelValue, () => {
  initFileList()
}, { immediate: true })
defineExpose({
  clearFiles
})
</script>

<style scoped>
.upload-container {
  .upload-tip {
    font-size: 12px;
    color: #909399;
    margin-top: 8px;
  }
}

:deep(.el-upload--picture-card) {
  --el-upload-picture-card-size: 100px;
}

:deep(.el-upload-list--picture-card) {
  --el-upload-list-picture-card-size: 100px;
}

:deep(.el-upload-list__item) {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

:deep(.el-upload-list__item-name) {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

:deep(.el-upload-list__item-actions) {
  display: flex;
  gap: 8px;
}
</style>